var exec = require('child_process').exec;

exports.gamelog = function(query, resp, callback) {
    resp.ispage = true;

    var allData = '';
    var sid = +query.sid || 0;
    var page = +query.page || 0;
    var uid = 0;

    async.series([
        function(cb) {
            if (!query.openid) {
                cb('invalid params');
                return;
            }
            
            if (gServers.error) {
                cb('servers error');
                return;
            }
            
            var db = gServers.getGameDB(sid);
            if (!db) {
                cb('invalid server');
                return;
            }

            db.collection('plat').findOne({_id: query.openid}, {}, function(err, result) {
                if (err || !result) {
                    cb('db error');
                    return;
                }

                uid = result.uid;
                cb();
            });
        },
        function(cb) {
            var cmd = util.format('%s/game querylog %d %d %d', gToolPath, sid, uid, page);
            if (query.word) {
               cmd = util.format('%s "%s"', cmd, query.word); 
            }

            last = exec(cmd, {maxBuffer:1024*1024});
            last.stdout.on('data', function (data) {
                allData += data;
            });

            last.stderr.on('data', function(data) {
                allData += data;
            });

            last.on('exit', function (code) {
                allData = allData.split('\n');
                var dataCount = allData.length;
                if (dataCount > 2000) {
                    allData = allData.slice(0, 2000);
                    allData.push(util.format("<H1>2000/%d条, 数据未全部显示, 请过滤关键字查询<H1>", dataCount));
                }
                allData = allData.join('<br/>');
                cb();
            });
        }
    ], function(err, results) {
        if (err) {
            allData = err;
            resp.code = 1;
            resp.desc = err;
        }
        resp.data = allData;
        callback();
    });
}

exports.gamerecord = function(query, resp, callback) {
    var sid = 0;
    var openId = query.openId;
    var dateTime = '';
    var type = '';
    var allData = '';
    resp.data = [];

    var typeIndex = {
        //[时间, 角色Id, 操作, 角色等级, 道具Id, 道具类型, 之前数量, 当前数量, 获得数量]
        'AddItem': [4, 5, 1, 9, 10, 11, 12, 13, 14],
        //[时间, 角色Id, 操作, 角色等级, 道具Id, 道具类型, 之前数量, 当前数量, 使用数量]
        'UseItem': [4, 5, 1, 9, 10, 11, 12, 13, 14],
    }

    async.series([
        function(cb) {
            if (isNaN(query.sid) || !query.openid || !query.stamp || !query.type) {
                cb('invalid params'); return;
            }
            
            sid = +query.sid;
            var db = gServers.getGameDB(sid);
            if (!db) {
                cb('invalid server'); return;
            }
           
            if (!typeIndex[query.type]) {
                cb('invalid type'); return;
            }
            
            openId = query.openid;
            dateTime = Date.createFromStamp(+query.stamp).format('yyyyMMdd');
            type = query.type;
            cb();
        },
        function(cb) {
            var cmd = util.format('%s/game queryrecord %d %s %s %s', gToolPath, sid, openId, dateTime, type);
            last = exec(cmd);

            last.stdout.on('data', function (data) {
                allData += data;
            });

            last.on('exit', function (code) {
                if (code) {
                    cb('cmd failed'); return;
                }
                cb();
            });
        }
    ], function(err, results) {
        do {
            if (err) {
                resp.code = 1; resp.desc = err; break;
            }

            if (!allData) {
                resp.code = 2; resp.desc = 'no data'; break;
            }

            var itemIndex = typeIndex[type];
            var maxIndex = Math.max.apply(null, itemIndex);

            allData = allData.split('\n');
            for (var i = 0, len = allData.length; i < len; ++i) {
                var items = allData[i].split('|');
                if (items.length >= maxIndex) {
                    var itemResult = [];
                    itemIndex.forEach(function(index) {
                        itemResult.push(items[index]);
                    });
                    resp.data.push(itemResult);
                }
            }
        } while (false);

        callback();
    });
}

exports.newServer = function(query, resp, callback) {
    if (isNaN(query.sid) || isNaN(query.time)) {
        resp.code = 1; resp.desc = 'invalid params'; 
        callback(); return;
    }
        
    var serverId = +query.sid;
    var time = Date.createFromStamp(+query.time).zeroTime().getStamp();
    var firstLeagueWarTime = time + 86400 + 13*3600;

    var outData = '';
    var errData = '';
    last = exec(util.format('%s/game open %d %d', gToolPath, serverId, firstLeagueWarTime));

    last.stdout.on('data', function (data) {
        outData += data;
    });

    last.stderr.on('data', function(data) {
        errData += data;
        resp.code = 1; resp.desc += data;
    });

    last.on('exit', function (code) {
        if (code) {
            resp.code = code; resp.desc = 'cmd faild'; resp.data = errData;
        } else {
            resp.data = outData;
        }

        callback();
    });
}

exports.tools = function(query, resp, callback) {
    if (isNaN(query.sid)) {
        resp.code = 1; resp.desc = 'invalid params';
        callback(); return;
    }

    var serverId = +query.sid;
    var cmd = "";
    
    switch (query.cmd) {
        case 'status':
            cmd = util.format('%s/game pure.status %d', gToolPath, serverId);
            break;
        case 'recover':
            cmd = util.format('%s/game pure.recover %d', gToolPath, serverId);
            break;
        case 'frestart':
            cmd = util.format('%s/game pure.frestart %d', gToolPath, serverId);
            break;
        case 'mem':
            cmd = util.format('%s/game pure.mem %d', gToolPath, serverId);
            break;
        default:
            resp.code = 1; resp.desc = 'unknown cmd';
            callback(); return;
            break;
    }

    var allData = '';
    last = exec(cmd);

    last.stdout.on('data', function (data) {
        allData += data;
    });

    last.stderr.on('data', function(data) {
        resp.code = 1; resp.desc += data;
    });

    last.on('exit', function (code) {
        if (code) {
            resp.code = code; resp.desc = 'cmd faild';
        }

        resp.data = allData;
        callback();
    });
}

exports.cloudBattleTools = function(query, resp, callback) {
    if (isNaN(query.sid)) {
        resp.code = 1; resp.desc = 'invalid params';
        callback(); return;
    }

    var sid = +query.sid;
    var cmd = "";
    
    switch (query.cmd) {
        case 'status':
            cmd = util.format('%s/cloud_battle pure.status %d', gToolPath, sid);
            break;
        case 'restart':
            cmd = util.format('%s/cloud_battle pure.restart %d', gToolPath, sid);
            break;
        default:
            resp.code = 1; resp.desc = 'unknown cmd';
            callback(); return;
            break;
    }

    var allData = '';
    last = exec(cmd);

    last.stdout.on('data', function (data) {
        allData += data;
    });

    last.stderr.on('data', function(data) {
        resp.code = 1; resp.desc += data;
    });

    last.on('exit', function (code) {
        if (code) {
            resp.code = code; resp.desc = 'cmd faild';
        }

        resp.data = allData;
        LOG(util.format('cloudBattleTools query=%j data=%s', query, allData));
        callback();
    });
}

/**
 * 查询玩家角色
 * @param query
 * @param resp
 * @param callback
 */
exports.queryUserPlayer = function(query, resp, callback) {
    if (!query.openid) {
        resp.code = 1; resp.desc = 'invalid params';
        callback(); return;
    }

    _queryUserPlayer(query.openid, function(err, res){
        resp.code = 0;
        resp.data = res;
        callback();
    });
};

/**
 * 批量查询玩家角色信息
 * @param query
 * @param resp
 * @param callback
 */
exports.queryUserPlayers = function(query, resp, callback) {
    var openidStr = query.openids;

    // 检查参数
    if (!openidStr)
    {
        resp.code = 1; resp.desc = 'invalid params';
        callback(); return;
    }

    // 需要查询的玩家ID数组
    var openidArr = openidStr.split(",");

    var _Sum = ["openid,uid,区服,合区后真实区服,角色名,等级,客户端IP,注册时间,最后登录时间,最后登录服务器"];

    async.eachSeries(openidArr, function(openid, esCb){
        _queryUserPlayer(openid, function(err, res){
            if (err) _Sum.push(util.format("%j", err));
            else {
                res.forEach(function(charactor){
                    // 格式化时间戳
                    charactor[7] = Date.createFromStamp(charactor[7]).stdFormatedString();
                    _Sum.push(charactor.join(","));
                });
            }
            esCb();
        });
    }, function(err){
        resp.plain = true;
        resp.data = _Sum.join("\n");
        callback();
    });
};

/**
 * 设置任务服务器
 * @param query
 * @param resp
 * @param callback
 */
exports.setTaskServer = function(query, resp, callback){
    var openid = query.openid;
    var sid = +query.sid;

    var sidStr = "s" + (sid + 1);

    var sql = gMysqlPool.format("UPDATE login SET task_server=? WHERE openid=?", [sidStr, openid]);
    gMysqlPool.query(sql, function(err, res){
        if (err) {
            LOG(err);
            resp.code = 1;
            resp.desc = util.format("%j", err);
        } else {
            resp.code = 0;
        }
        callback && callback();
    });
};

/**
 * 查询任务集市数据
 * @param query
 * @param resp
 * @param callback
 */
exports.queryTaskInfo = function(query, resp, callback){
    var openid = query.openid;
    var sid = -1;
    var rd = [];

    async.series([
        // 查询任务服务器
        function(cb) {
            var sql = gMysqlPool.format("SELECT * FROM login WHERE openid=?", [openid]);
            gMysqlPool.query(sql, function(err, res){
                if (err) LOG(err);
                LOG(res);
                if (res && res.length > 0) {
                    var task_server = res[0]['task_server'];
                    LOG("task_server " + task_server);

                    sid = +(task_server.substr(1)) - 1;
                    LOG("sid " + sid);
                }
                cb(null);
            });
        },
        // 查询数据
        function(cb) {
            if (sid == -1) {
                cb(null);
                return;
            }

            var db = gServers.getGameDB(sid);
            if (!db) {
                cb("db error");
                return;
            }

            var uids = [];
            db.collection("plat").find({"_id":openid}).toArray(function(err, res){
                if (err) {
                    LOG(err);
                    cb(util.format("%j", err));
                } else {
                    var plat = res[0];
                    if (plat.uids) {
                        uids = plat.uids;
                    } else {
                        uids.push(plat.uid);
                    }

                    db.collection("user").find({_id:{$in:uids}}).toArray(function(err, res){
                        if (err) {
                            LOG(err);
                            cb(util.format("%j", err));
                        } else {
                            res.forEach(function(chara){
                                var activity = chara['activity'];
                                rd.push({
                                    sid: sid,
                                    uid: chara._id,
                                    app_contract_id: activity.app_contract_id,
                                    contract_task_v3: activity.contract_task_v3,
                                    contract_task_reward_v3: activity.contract_task_reward_v3
                                });
                            });

                            cb(null);
                        }
                    });
                }
            });
        }
    ], function(err){
        if (err) {
            resp.code = 1;
            resp.desc = err;
            callback && callback();
        } else {
            resp.code = 0;
            resp.data = rd;
            callback && callback();
        }
    });
};

//-----------------------------------------------------------------------------
/**
 * 查询用户角色信息
 * @param openid
 * @param fn
 * @private
 */
function _queryUserPlayer(openid, fn) {
    var playerArr = [];
    var lastLoginSid = -1;
    async.series([
        // 查询最后登录服务器
        function(cb) {
            var sql = gMysqlPool.format("SELECT * FROM login WHERE openid=?", [openid]);
            gMysqlPool.query(sql, function(err, res){
                if (err) LOG(err);
                LOG(res);
                if (res && res.length > 0) {
                    var _sid = res[0]['server'];
                    LOG("_sid " + _sid);
                    if (config.platform.name == "qzone") {
                        var _sids = _sid.split(',');
                        _sid = _sids[_sids.length - 1];
                        _sid = _sid.substr(1);
                        lastLoginSid = +_sid;
                    } else {
                        lastLoginSid = +_sid;
                    }
                }
                cb(null);
            });
        },
        function(cb) {
            // 查询玩家角色列表
            async.each(gServers.getSids(), function(sid, esCb) {
                var db = gServers.getGameDB(sid);
                if (!db) {
                    esCb();
                    return;
                }

                var dbPlat = db.collection("plat");
                dbPlat.find({"_id":openid}).toArray(function(err, res){
                    if (err) {
                        LOG(err);
                        esCb();
                    }
                    else if (res) {
                        var _plat = res[0];
                        if (_plat) {
                            var platUids = _plat.uids || [];
                            if (_plat.uid && (platUids.indexOf(_plat.uid) == -1)) {
                                platUids.push(_plat.uid);
                            }
                            async.eachSeries(platUids, function(uid, _esCb){
                                _getCharaInfo(db, sid, uid, function(err, res){
                                    if (err) LOG(err);
                                    var _arr = [openid, uid, _getOriginSID(uid), sid];
                                    if (!err) {
                                        _arr = _arr.concat(res);
                                        playerArr.push(_arr.concat([lastLoginSid]));
                                    }
                                    _esCb();
                                });
                            }, function(err, res){
                                esCb();
                            });
                        } else {
                            esCb();
                        }
                    }
                });
            }, function(err){
                cb();
            });
        }
    ], function(err){
        fn(err, playerArr);
    });

    /**
     * 从UID获取SID
     * @param uid
     * @returns {number}
     * @private
     */
    function _getOriginSID(uid) {
        var sid = Math.floor(uid/1000000);
        if (uid > 100000000) {
            sid = Math.floor((uid-100000000)/100000);
        }
        return sid - 1;
    }

    /**
     * 查询角色详细信息
     * @param db
     * @param sid
     * @param uid
     * @param fn
     * @private
     */
    function _getCharaInfo(db, sid, uid, fn){
        db.collection("user").find({_id:uid}).toArray(function(err, res){
            if (err) fn(err);
            else {
                if (res && res.length > 0) {
                    var charaInfo = res[0];
                    var _ret = [
                        charaInfo.info.un,
                        charaInfo.status.level,
                        charaInfo.info.createIP,
                        charaInfo.info.create,
                        charaInfo.mark.day
                    ];
                    fn(null, _ret);
                    return;
                }

                fn("NO PLAYER " + sid);
            }
        });
    }
}
